import { Component, FlowComponent, JSXElement, createEffect, createSignal } from 'solid-js'
import S from './Settings.module.styl'
import { Config, useGame } from './game'
import { assertNot } from './utils'

type Input = FlowComponent<{
  onInput: (v: string) => void
}, string>

const Input: Input = prop => {
  const [err, setErr] = createSignal(false)
  const [val, setVal] = createSignal(prop.children, { equals: false })
  const [focus, setFocus] = createSignal(false)

  createEffect(() => {
    if (!focus()) {
      setVal(prop.children)
      setErr(false)
    }
  })

  return <input
    type="text"
    class={S.input}
    classList={{ [S.err]: err() }}
    value={val()}
    onInput={e => {
      try {
        prop.onInput(e.target.value)
        setErr(false)
      } catch (e) {
        setErr(true)
      }
    }}
    onFocus={() => setFocus(true)}
    onBlur={() => setFocus(false)}
  />
}

const Option: FlowComponent<{ title: JSXElement, desc: JSXElement }> = prop =>
  <>
    <div class={S.desc}>
      <strong>{prop.title}</strong><br />
      {prop.desc}
    </div>
    <div>{prop.children}</div>
  </>

type KeyName<Ty = any, K extends keyof Config = keyof Config> =
  K extends K ? Config[K] extends Ty ? K : never : '!'

const InputConfig = <K extends KeyName>(prop: {
  key: K
  ser: (v: Config[K]) => string
  de: (v: string) => Config[K]
}) => {
  const { store, setCfg } = useGame()
  return <Input onInput={v => setCfg(prop.key, prop.de(v))}>
    {prop.ser(store[prop.key])}
  </Input>
}

const CheckboxConfig = (prop: {
  key: KeyName<boolean>
}) => {
  const { store, setCfg } = useGame()
  return <input
    type="checkbox"
    checked={store[prop.key]}
    onInput={e => setCfg(prop.key, e.target.checked)}
  />
}

const Settings: Component = () => {
  const { clearData } = useGame()
  const deNum = (v: string) => assertNot(Number(v), isNaN)

  return <div class={S.view}>
    <p class={S.line}>修改设置将会自动保存到本地，但若输入无效则会忽略</p>
    <Option title="本地保存胜负统计" desc="于「统计」处查看">
      <CheckboxConfig key="saveStat"></CheckboxConfig>
    </Option>
    <Option title="结束后自动重来时延" desc="毫秒，非正数则不自动重来">
      <InputConfig key="autoRematch" de={deNum} ser={String}></InputConfig>
    </Option>
    <Option title="招数规则" desc="开发用，请勿随意更改">
      <InputConfig key="skill" de={JSON.parse} ser={JSON.stringify}></InputConfig>
    </Option>
    <Option title="智能引擎权重" desc="开发用，请勿随意更改">
      <InputConfig key="agent" de={JSON.parse} ser={JSON.stringify}></InputConfig>
    </Option>
    <Option title="清除本地数据" desc={<>谨慎！全部数据恢复默认<br />包括设置和统计信息</>}>
      <button type="button" onClick={clearData}>全部清除</button>
    </Option>
  </div>
}

export default Settings
